#!/usr/bin/python2.4
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This script is designed for command line access to the userdb functions
defined in gvn/lib/userdb.py, and used by some hooks like check_owners, 
as well as the mod_authn_dir.so svn access apache module

This script assumes that users are already created by create-owners-groups
which adds and deletes user entries as they are added to your local
user list (unix passwd/yp/ldap/other).
This is why it doesn't have commands to add/remove users doing so would get
undone by the create-owners-groups cron job.
"""

# Change this for your local install
SVN_USERDB_PATH = "/opt/svn/userdb"

import optparse
import os
import sys

import gvn.userdb


def LockUser(userdb, argv=None):
  if not argv or not argv[0]:
    return

  userdb.LockUser(argv[0])
  print "%s:%s:%s" % userdb.ReadUserPassword(argv[0])

def UnLockUser(userdb, argv=None):
  if not argv or not argv[0]:
    return

  userdb.UnLockUser(argv[0])
  print "%s:%s:%s" % userdb.ReadUserPassword(argv[0])

def ResetUser(userdb, argv=None):
  if not argv or not argv[0]:
    return

  print "%s:%s:%s" % userdb.RandomizeUserPassword(argv[0])

def ShowUser(userdb, argv=None):
  if not argv or not argv[0]:
    return

  print "%s:%s:%s" % userdb.ReadUserPassword(argv[0])

def ShowUsers(userdb, argv=None):
  if not argv:
    for user in userdb.GetAllUsers():
      print user
  else:
    for user in argv:
      print "%s:%s:%s" % userdb.ReadUserPassword(user)

def SetUser(userdb, argv=None):
  if not argv or len(argv) != 2:
    return

  print "%s:%s:%s" % userdb.WriteUserPassword(argv[0], argv[1])

def CreateUser(userdb, argv=None):
  '''Since the docs are the source, there you go:
  create calls CreateSvnOnlyUser to make a new user with a random password
  and add a special SVN_ONLY_FLAG file to indicate to populate-userdb
  or some other script that syncs userdb with some external database
  (including deletes), that user we just made should not be deleted at
  the next sync run.'''

  if not argv or not argv[0]:
    return

  print "%s:%s:%s" % userdb.CreateSvnOnlyUser(argv[0])

def DeleteUser(userdb, argv=None):
  '''Manually delete a user that is not auto deleted by DB syncing scripts.
  '''
  if not argv or not argv[0]:
    return

  userdb.DeleteUser(argv[0])
  print "%s deleted" % argv[0]




def main(options, args):
  commands = [
    (['lock',  'user'],  LockUser),
    (['unlock','user'],  UnLockUser),
    (['show',  'user'],  ShowUser),
    (['show',  'users'], ShowUsers),
    (['set',   'user'],  SetUser),
    (['reset', 'user'],  ResetUser),
    (['create', 'user'],  CreateUser),
    (['delete', 'user'],  DeleteUser),
    ]

  if len(args) == 0 or args[0] == 'help':
    for (cmd_list, funcname) in commands:
      if cmd_list[1] == "users":
        print "%s [user1 user2 user| ] (nothing = all users)" % \
                                                        ' '.join(cmd_list)
      else:
        print "%s <username>" % ' '.join(cmd_list)
    return 0

  func = None
  for i in xrange(len(args) + 1):
    cmd_subset = args[:i]
    for (cmd_list, funcname) in commands:
      if cmd_subset == cmd_list:
        func = funcname
        args = args[i:]
        break
    if func is not None:
      break

  if func is None:
    print >>sys.stderr, "unknown command string"
    return 1

  userdb = gvn.userdb.UserDB(options.userdb_dir)
  rval = func(userdb, args)
  return rval


if __name__ == '__main__':
  parser = optparse.OptionParser()

  parser.add_option('--userdb-dir',
                    action="store",
                    dest="userdb_dir",
                    default=SVN_USERDB_PATH)

  (options, args) = parser.parse_args()
  sys.exit(main(options, args))
